﻿// @ts-ignore
import CryptoJS from 'crypto-js';

// 确保密钥和IV是正确长度
const key = CryptoJS.enc.Utf8.parse('esignencrypteddataurlencoded1234');
const iv = CryptoJS.enc.Utf8.parse('esignencrypted12');

// 类型定义
type EncryptableData = string | number | boolean | object | Array<any> | null | undefined;

class EnhancedCrypto {
    /**
     * 加密方法 - 支持多种数据类型
     */
    static encrypt(data: EncryptableData): string {
        try {
            // 处理不同类型的数据
            let dataToEncrypt: string;

            if (data === null || data === undefined) {
                dataToEncrypt = '';
            } else if (typeof data === 'object') {
                // 对象和数组转换为JSON字符串
                dataToEncrypt = JSON.stringify(data);
            } else if (typeof data === 'number' || typeof data === 'boolean') {
                // 数字和布尔值转换为字符串
                dataToEncrypt = data.toString();
            } else {
                // 字符串直接使用
                dataToEncrypt = data;
            }

            // 将明文转换为WordArray
            const srcs = CryptoJS.enc.Utf8.parse(dataToEncrypt);

            // 加密
            const encrypted = CryptoJS.AES.encrypt(srcs, key, {
                iv: iv,
                mode: CryptoJS.mode.CBC,
                padding: CryptoJS.pad.Pkcs7,
            });

            // 返回Base64字符串
            return encrypted.toString();
        } catch (error:any) {
            console.error('加密失败:', error);
            throw new Error(`加密失败: ${error.message}`);
        }
    }

    /**
     * 解密方法 - 返回原始数据类型
     */
    static decrypt<T = any>(encryptedBase64: string): T {
        try {
            // 将Base64字符串转换为CryptoJS的WordArray
            const encryptedData = CryptoJS.enc.Base64.parse(encryptedBase64);

            // 解密
            const decrypt = CryptoJS.AES.decrypt({ ciphertext: encryptedData } as any, key, {
                iv: iv,
                mode: CryptoJS.mode.CBC,
                padding: CryptoJS.pad.Pkcs7,
            });

            // 转换为UTF8字符串
            const decryptedStr = decrypt.toString(CryptoJS.enc.Utf8);

            if (!decryptedStr) {
                return null as T;
            }

            // 尝试解析为JSON（如果是对象或数组）
            try {
                return JSON.parse(decryptedStr) as T;
            } catch {
                // 如果不是JSON，返回原始字符串
                return decryptedStr as T;
            }
        } catch (error:any) {
            console.error('解密失败:', error);
            throw new Error(`解密失败: ${error.message}`);
        }
    }

    /**
     * 解密为字符串（明确返回字符串类型）
     */
    static decryptString(encryptedBase64: string): string {
        const result = this.decrypt(encryptedBase64);
        return typeof result === 'string' ? result : String(result);
    }

    /**
     * 解密为数字
     */
    static decryptNumber(encryptedBase64: string): number {
        const result = this.decrypt(encryptedBase64);
        if (typeof result === 'number') return result;
        const num = Number(result);
        return isNaN(num) ? 0 : num;
    }

    /**
     * 解密为布尔值
     */
    static decryptBoolean(encryptedBase64: string): boolean {
        const result = this.decrypt(encryptedBase64);
        if (typeof result === 'boolean') return result;
        return result === 'true' || result === '1';
    }

    /**
     * URL安全的加密（用于路由参数）
     */
    static encryptForUrl(data: EncryptableData): string {
        const encrypted = this.encrypt(data);
        return encodeURIComponent(encrypted);
    }

    /**
     * URL安全的解密
     */
    static decryptFromUrl<T = any>(encryptedUrl: string): T {
        const decoded = decodeURIComponent(encryptedUrl);
        return this.decrypt<T>(decoded);
    }

    /**
     * 加密对象（明确类型）
     */
    static encryptObject<T extends object>(obj: T): string {
        return this.encrypt(obj);
    }

    /**
     * 解密为对象
     */
    static decryptObject<T extends object>(encryptedBase64: string): T {
        return this.decrypt<T>(encryptedBase64);
    }

    /**
     * 加密数组
     */
    static encryptArray<T>(array: T[]): string {
        return this.encrypt(array);
    }

    /**
     * 解密为数组
     */
    static decryptArray<T>(encryptedBase64: string): T[] {
        return this.decrypt<T[]>(encryptedBase64);
    }

    /**
     * 验证加密数据是否有效
     */
    static isValidEncryptedData(encryptedBase64: string): boolean {
        try {
            this.decrypt(encryptedBase64);
            return true;
        } catch {
            return false;
        }
    }
}

// 导出默认实例
export default EnhancedCrypto;

// 也导出旧的函数名以保持兼容性
export const Encrypt = EnhancedCrypto.encrypt;
export const Decrypt = EnhancedCrypto.decrypt;
